{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from fit.datamodules.tomo_rec import Kanji_TRecFITDM\n",
    "from fit.utils.tomo_utils import get_polar_rfft_coords_2D, get_polar_rfft_coords_sinogram\n",
    "from fit.utils import denormalize, convert2DFT\n",
    "from fit.modules import TRecTransformerModule\n",
    "\n",
    "from matplotlib import pyplot as plt\n",
    "\n",
    "import torch\n",
    "\n",
    "import numpy as np\n",
    "\n",
    "from pytorch_lightning import Trainer, seed_everything\n",
    "from pytorch_lightning.callbacks import ModelCheckpoint\n",
    "\n",
    "import wget\n",
    "from os.path import exists"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Global seed set to 22122020\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "22122020"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "seed_everything(22122020)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "dm = Kanji_TRecFITDM(root_dir='./datamodules/data/Kanji', batch_size=8, num_angles=33)\n",
    "# FIT: TRec + FBP vs FIT: TRec\n",
    "with_fbp = True\n",
    "\n",
    "dm.prepare_data()\n",
    "dm.setup()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "angles = dm.gt_ds.get_ray_trafo().geometry.angles\n",
    "det_len = dm.gt_ds.get_ray_trafo().geometry.detector.shape[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "img_shape = dm.gt_shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "proj_r, proj_phi, src_flatten = get_polar_rfft_coords_sinogram(angles=angles, \n",
    "                                                               det_len=det_len)\n",
    "target_r, target_phi, dst_flatten, order = get_polar_rfft_coords_2D(img_shape=img_shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "n_heads = 8\n",
    "d_query = 32\n",
    "model = TRecTransformerModule(d_model=n_heads * d_query, \n",
    "                              sinogram_coords=(proj_r, proj_phi),\n",
    "                              target_coords=(target_r, target_phi),\n",
    "                              src_flatten_coords=src_flatten, \n",
    "                              dst_flatten_coords=dst_flatten, \n",
    "                              dst_order=order,\n",
    "                              angles=angles, \n",
    "                              img_shape=img_shape,\n",
    "                              detector_len=det_len,\n",
    "                              loss='prod', \n",
    "                              use_fbp=with_fbp, \n",
    "                              init_bin_factor=1, \n",
    "                              bin_factor_cd=5,\n",
    "                              lr=0.0001, \n",
    "                              weight_decay=0.01, \n",
    "                              attention_type='linear', \n",
    "                              n_layers=4,\n",
    "                              n_heads=n_heads, \n",
    "                              d_query=d_query, \n",
    "                              dropout=0.1, \n",
    "                              attention_dropout=0.1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "GPU available: True, used: True\n",
      "TPU available: False, using: 0 TPU cores\n"
     ]
    }
   ],
   "source": [
    "trainer = Trainer(max_epochs=120, \n",
    "                  gpus=1,\n",
    "                  checkpoint_callback=ModelCheckpoint(\n",
    "                                            dirpath=None,\n",
    "                                            save_top_k=1,\n",
    "                                            verbose=False,\n",
    "                                            save_last=True,\n",
    "                                            monitor='Train/avg_val_mse',\n",
    "                                            mode='min',\n",
    "                                            prefix='best_val_loss_'\n",
    "                                        ), \n",
    "                  deterministic=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Uncomment the next line if you want to train your own model. \n",
    "# trainer.fit(model, datamodule=dm);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "if not exists('./models/trec_kanji/kanji_trec.ckpt'):\n",
    "    wget.download('https://cloud.mpi-cbg.de/index.php/s/0ksUkIsWsQfzsXv/download',\n",
    "                  out='./models/trec_kanji/kanji_trec.ckpt')\n",
    "    \n",
    "if not exists('./models/trec_kanji/kanji_trec_fbp.ckpt'):\n",
    "    wget.download('https://cloud.mpi-cbg.de/index.php/s/GQWwEYarKse69W1/download',\n",
    "                  out='./models/trec_kanji/kanji_trec_fbp.ckpt')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "if with_fbp:\n",
    "    path = './models/trec_kanji/kanji_trec_fbp.ckpt'\n",
    "else:\n",
    "    path = './models/trec_kanji/kanji_trec.ckpt'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = TRecTransformerModule.load_from_checkpoint(path, \n",
    "                                               sinogram_coords=(proj_r, proj_phi),\n",
    "                              target_coords=(target_r, target_phi),\n",
    "                              src_flatten_coords=src_flatten, \n",
    "                              dst_flatten_coords=dst_flatten, \n",
    "                              dst_order=order, angles=angles, strict=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]\n",
      "/home/tbuchhol/Programs/miniconda3/envs/fit_test/lib/python3.7/site-packages/pytorch_lightning/utilities/distributed.py:52: UserWarning: The dataloader, test dataloader 0, does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` (try 56 which is the number of cpus on this machine) in the `DataLoader` init to improve performance.\n",
      "  warnings.warn(*args, **kwargs)\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "878dcf41f07b42008c10b9b56c3dc296",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Testing: 0it [00:00, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/tbuchhol/.local/lib/python3.7/site-packages/torch/nn/functional.py:1628: UserWarning: nn.functional.tanh is deprecated. Use torch.tanh instead.\n",
      "  warnings.warn(\"nn.functional.tanh is deprecated. Use torch.tanh instead.\")\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "bin_factor set to 1.\n",
      "--------------------------------------------------------------------------------\n",
      "DATALOADER:0 TEST RESULTS\n",
      "{'Mean PSNR': array(30.720849990844727, dtype=float32),\n",
      " 'SEM PSNR': array(0.031072352081537247, dtype=float32)}\n",
      "--------------------------------------------------------------------------------\n"
     ]
    }
   ],
   "source": [
    "test_res = trainer.test(model, datamodule=dm)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "for x_fc, fbp_fc, y_fc, y_real, (amp_min, amp_max) in dm.test_dataloader():\n",
    "    break"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "model.cpu();"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/tbuchhol/Gitrepos/FourierImageTransformer/fit/modules/TRecTransformerModule.py:357: UserWarning: Casting complex values to real discards the imaginary part (Triggered internally at  /pytorch/aten/src/ATen/native/Copy.cpp:162.)\n",
      "  pred_fc_[:, :tmp.shape[1]] = tmp\n"
     ]
    }
   ],
   "source": [
    "pred_img, pred_img_before_conv = model.get_imgs(x_fc, fbp_fc, y_fc, amp_min, amp_max)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Before the projection we normalized the image, now we undo this for the visualization.\n",
    "# After denormalization we set all pixels outside of the projection-area to zero\n",
    "pred_img = denormalize(pred_img, dm.mean, dm.std) * dm.__get_circle__()\n",
    "y_real = denormalize(y_real, dm.mean, dm.std) * dm.__get_circle__()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "dft_fbp = convert2DFT(x=fbp_fc[:,model.dst_flatten_order], amp_min=amp_min, amp_max=amp_max,\n",
    "                              dst_flatten_order=model.dst_flatten_order, img_shape=model.hparams.img_shape)\n",
    "fbp_img = torch.roll(torch.fft.irfftn(model.mask * dft_fbp[0], s=2 * (model.hparams.img_shape,)),\n",
    "                     2 * (model.hparams.img_shape // 2,), (0, 1))\n",
    "\n",
    "fbp_img = (fbp_img - fbp_img.min())*255/(fbp_img.max() - fbp_img.min())\n",
    "fbp_img = fbp_img * dm.__get_circle__()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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/g7XReO8ac6r5tpjsdeicePGOdvC59K8efOc+/7Sl3J32W3btuXcnj0qfK577LFHpdtyfTchGgKnnXZa2fLixYtzfjauI1YdOPbdcccdTl944YU5t99nn32cbteundMffPBBAa0rLbk8IFwvcsqUKcVujhCppJT1wNhHeuONNzp9/fXXO21mTh9wwAHFaVgtkM91lz8tf/TLmRBCCCGEEEKkAL2cCSGEEEIIIUQK0MuZEEIIIYQQQqQAec5KRNu2bZ3u1auX05s3by5b/vjjj906zltOgj//2WefOc2+Lc4HPvLII51mf8OGDRucZp9X7FHjHG0+t3/96185j8Vw3STeno/H++M6Sdye+Fpxfbg+ffo4zZ606dOnV9ZsIVILewe4rmGSzywfeHwyXGuM6wiNGzfOaY5l69evd5o9rfUFjltJ/g95PkRdpZSesnyZNGmS06eeeqrTXHf1tddeK3aTUoniU/7olzMhhBBCCCGESAF6ORNCCCGEEEKIFKCXMyGEEEIIIYRIAcZ1n4p6MLPSHayWYX9S7CkDytffadmyZdkye7jYZ8Wwr4r9CLw9e6WY0aNHO83+uEceecRp9nXE7eHz/uSTT5zesWOH01wHZMuWLU7zdeNzb9asmdPs9WP/zNatW53eZZddypbff/995IL9bvG2QMPKow4h5GeMTBkNKTYV4uFgzxh7xGqaL774wulhw4Y5feKJJzrNdYe4RmQuks6tRYsWTnPsYm9v06ZNnebY1rt3b6cff/xxpzn2xe1J8u4lodhUt1B8qhvsu+++Tt9zzz1O//SnP3V68uTJRW9TZbBft3v37k63bt3a6dWrVzvNNSO5vm4hKD7plzMhhBBCCCGESAV6ORNCCCGEEEKIFKCXMyGEEEIIIYRIAfKcVZNTTjnFac6/XbRokdPsnWjfvr3TcW0h9ojttttuTrO3if0H7H1g/ZWvfMVprovWtWtXpzt37uz0o48+6jSfS5y7zHWH2A/HPo6ePXs63aFDh0r3DQDNmzd3mvszt43vA9d0iu/bM88849axB409J+xBY89Ko0aNnJ4xYwbqC3Xd11GfYtOgQYOc5n7JlNpHVgjcNvb2zps3L+f28RjkuMh+WObggw92+qijjnJ67733dprjJscq9nzwfeD79vbbb5ct//rXv3bruPZkofewPnk+6npsAupXfKrLnrJ8GTFihNPTpk1zmp+HCqFLly5ODx06NGdb+vbt63Rcn7Yitm/f7nTjxo2dnjp1atnyxRdfnHNfhdIQ4lN6v4WFEEIIIYQQogGhlzMhhBBCCCGESAFKa6wie+21l9NDhgxx+h//+IfTPGU7pyryNKWff/552TJPocxTMnN6HKfqxfsCyqfr8P44vWbPPfd0mtMgX3/9dad5eus43YevC7d9jz32cLpVq1ZOc1pip06dnOapspPSR+OSBUD5qf7j6WA57ZCnvV24cKHTnCLJbeFp/zmtavbs2air1PXUobocmzhNiMtHcL9bvny503UprZFTsDnWcco3j8Fx48aVLXMs4hjPJUf2228/p3l7vm58bF7PbU0iPleOPZdddpnTnE7ekNMc63psAupXfBKVM2rUqLJlfjY65phjnOY4z9YaLtXBsZO/B7p165azbfwMu+uuu1a6/2XLlrl1P/zhD51eu3ZtzmPlS32MT+n9FhZCCCGEEEKIBoRezoQQQgghhBAiBejlTAghhBBCCCFSgDxnlcDTJsdeJAD40Y9+5DRPnT9p0iSnecpU9nnF+cMrVqxw63hK5iSPCHvE2PfF+2OvRY8ePZxmXxbnE5900klOx1N582c515ino+frzNNT83TU7M/jPGg+N54uln0h8fZ8z5YuXer09OnTnX7ppZec5hxthu8L++3efPPNnNunibru66hLsYk9HBwPbrvtNqdfeeUVpx955BGn8/Ej8bGYpH0l+WN5fB555JFOczxYsmSJ0xxPrrvuOqdjPy1PVc+xhKenZ0/HV7/6Vac5pnP8YO8fx2nenj2p8bXh67ZgwQKnH3jgAae5LAgfK1/qksejrscmoG7HJx7Tzz33nNOjR492mr8X0wyX/uG5CNasWeM0+9J5yvkk31cMe9Rfe+01p8eOHet0kueVY0LS1Pr5sG3bNqcvv/xyp2u6rFB9iE/65UwIIYQQQgghUoBezoQQQgghhBAiBejlTAghhBBCCCFSQGGJ5/WIESNGOM1+BM7P7d69e879zZ071+l169Y5zfm/cY0I9iqw5jpkvXr1yql32203p7l+Bq/nc+O86TZt2jjN9X9iP8T8+fPdumnTpjnNHpHVq1c7zfXguK0ffvih01zLY8yYMU4PHz7caa4VEue7sx/z0EMPdbpZs2ZOv/fee06zR409LOyP2759u9ODBw92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\n",
      "text/plain": [
       "<Figure size 1080x360 with 3 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(15,5))\n",
    "plt.subplot(1,3,1)\n",
    "plt.imshow(fbp_img, cmap='gray', vmin=y_real[0].min(), vmax=y_real[0].max())\n",
    "plt.title('Filtered Backprojection');\n",
    "plt.subplot(1,3,2)\n",
    "plt.imshow(pred_img[0].detach(), cmap='gray', vmin=y_real[0].min(), vmax=y_real[0].max())\n",
    "plt.title('Prediction');\n",
    "plt.subplot(1,3,3)\n",
    "plt.imshow(y_real[0], cmap='gray')\n",
    "plt.title('Ground Truth');"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
